﻿using System.IO;
using System.Text.RegularExpressions;
using IQIGame.Onigao.Framework;
using IQIGame.Onigao.Game;
using UnityEditor;
using UnityEngine;
using AnimationCurveArr = IQIGame.Onigao.GamePlay.CameraCurveConfig.AnimationCurveArr;

namespace IQIGame.Onigao.GamePlay.Editors
{
    public class CameraMoveCurveExport
    {
        // private const string CameraAnimeFolder = "Assets/EditorConfig/BattleCameraConfig";
        private const string CamFbxRegex = @".*Assets/Res/04_ArtModel/(Character|Entity)/([a-zA-Z0-9_]+)/Camera/[a-zA-Z0-9_]+@[a-zA-Z0-9_]+_cam(_[0-9])?.fbx";
        private static readonly AnimationCurve DefaultCurve = AnimationCurve.Linear(0, 0, 0.1f, 0);

        [MenuItem("Assets/GameEditor/战斗->相机曲线导出", false, 1000)]
        static void GenCameraCurve()
        {
            var rAssets = Selection.objects;
            for (int i = 0; i < rAssets.Length; i++)
            {
                Export(rAssets[i]);
            }
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();

            void Export(Object rAsset)
            {
                var rPath = AssetDatabase.GetAssetPath(rAsset);
                Match match = Regex.Match(rPath, CamFbxRegex, RegexOptions.IgnoreCase);
                if (!match.Success)
                {
                    LogGame.LogError($"待导出文件需要放在ArtModel下角色或怪物的Camera下且命名规则为【角色@技能_cam[_XXX]】的fbx文件");
                    return;
                }
                string rRoleName = match.Groups[2].Value;

                var rGoAsset = rAsset as GameObject;
                var rClipAsset = AssetDatabase.LoadAssetAtPath<AnimationClip>(rPath);
                var rName = Path.GetFileNameWithoutExtension(rPath);
                if (rGoAsset && rClipAsset != null)
                {
                    var rAssetPath = "Assets/" + PathConstant.GetBattleCameraCurvePath(rRoleName, rName);
                    var rDirPath = Path.GetDirectoryName(rAssetPath);
                    if (!Directory.Exists(rDirPath))
                    {
                        Directory.CreateDirectory(rDirPath);
                    }
                    var rConfig = AssetDatabase.LoadAssetAtPath<CameraCurveConfig>(rAssetPath);
                    if (rConfig == null)
                    {
                        rConfig = ScriptableObject.CreateInstance<CameraCurveConfig>();
                        AssetDatabase.CreateAsset(rConfig, rAssetPath);
                    }
                    for (int i = 0; i < CameraCurveConfig.targetMaxNum; i++)
                    {
                        rConfig.targetPos[i] ??= new AnimationCurveArr(3);
                        rConfig.targetRot[i] ??= new AnimationCurveArr(4);
                    }

                    rConfig.rootRotation = rGoAsset.transform.rotation;
                    var rCamera001Trans = FindChild(rGoAsset.transform, "Camera001");
                    if (rCamera001Trans) // 指定为父节点的旋转
                    {
                        rConfig.rootRotation = rCamera001Trans.transform.parent.rotation;
                    }
                    rConfig.duration = rClipAsset.averageDuration;
                    UnityEditor.EditorCurveBinding[] curveBindings = AnimationUtility.GetCurveBindings(rClipAsset);
                    foreach (var curveBinding in curveBindings)
                    {
                        AnimationCurve[] rPosArr = null;
                        AnimationCurve[] rRotArr = null;
                        if (curveBinding.path.Contains("Camera001"))
                        {
                            rPosArr = rConfig.pos.value;
                            rRotArr = rConfig.rot.value;
                            if (curveBinding.propertyName.Contains("field of view"))
                            {
                                rConfig.fov = AnimationUtility.GetEditorCurve(rClipAsset, curveBinding);
                            }
                        }
                        else if (curveBinding.path.Contains("Target"))
                        {
                            var nTargetIndex = -1;
                            for (int i = 0; i < CameraCurveConfig.targetMaxNum; i++)
                            {
                                if (curveBinding.path.Contains($"Target00{i + 1}"))
                                {
                                    nTargetIndex = i;
                                    break;
                                }
                            }
                            if (nTargetIndex < 0)
                            {
                                continue;
                            }
                            
                            if (rConfig.targetPos[nTargetIndex] == null || rConfig.targetPos[nTargetIndex].value == null || rConfig.targetPos[nTargetIndex].value.Length < 3)
                            {
                                rConfig.targetPos[nTargetIndex] = new AnimationCurveArr(3);
                            }
                            if (rConfig.targetRot[nTargetIndex] == null || rConfig.targetRot[nTargetIndex].value == null || rConfig.targetRot[nTargetIndex].value.Length < 4)
                            {
                                rConfig.targetRot[nTargetIndex] = new AnimationCurveArr(4);
                            }
                            rPosArr = rConfig.targetPos[nTargetIndex].value;
                            rRotArr = rConfig.targetRot[nTargetIndex].value;
                        }
                        if (rPosArr != null && rRotArr != null)
                        {
                            if (curveBinding.propertyName.Contains("m_LocalPosition.x"))
                            {
                                rPosArr[0] = AnimationUtility.GetEditorCurve(rClipAsset, curveBinding);
                            }
                            else if (curveBinding.propertyName.Contains("m_LocalPosition.y"))
                            {
                                rPosArr[1] = AnimationUtility.GetEditorCurve(rClipAsset, curveBinding);
                            }
                            else if (curveBinding.propertyName.Contains("m_LocalPosition.z"))
                            {
                                rPosArr[2] = AnimationUtility.GetEditorCurve(rClipAsset, curveBinding);
                            }
                            else if (curveBinding.propertyName.Contains("m_LocalRotation.x"))
                            {
                                rRotArr[0] = AnimationUtility.GetEditorCurve(rClipAsset, curveBinding);
                            }
                            else if (curveBinding.propertyName.Contains("m_LocalRotation.y"))
                            {
                                rRotArr[1] = AnimationUtility.GetEditorCurve(rClipAsset, curveBinding);
                            }
                            else if (curveBinding.propertyName.Contains("m_LocalRotation.z"))
                            {
                                rRotArr[2] = AnimationUtility.GetEditorCurve(rClipAsset, curveBinding);
                            }
                            else if (curveBinding.propertyName.Contains("m_LocalRotation.w"))
                            {
                                rRotArr[3] = AnimationUtility.GetEditorCurve(rClipAsset, curveBinding);
                            }
                        }
                    }

                    // 把空的curve给设置上值
                    // for (int i = 0; i < rConfig.targetPos.Length; i++)
                    // {
                    //     if (rConfig.targetPos[i] == null || rConfig.targetPos[i].value == null)
                    //     {
                    //         rConfig.targetPos[i] = new AnimationCurveArr(3);
                    //     }
                    //     for (int j = 0; j < rConfig.targetPos[i].value.Length; j++)
                    //     {
                    //         if (rConfig.targetPos[i].value[j] == null)
                    //         {
                    //             rConfig.targetPos[i].value[j] = DefaultCurve;
                    //         }
                    //     }
                    // }
                    // for (int i = 0; i < rConfig.targetRot.Length; i++)
                    // {
                    //     if (rConfig.targetRot[i] == null || rConfig.targetRot[i].value == null)
                    //     {
                    //         rConfig.targetRot[i] = new AnimationCurveArr(4);
                    //     }
                    //     for (int j = 0; j < rConfig.targetRot[i].value.Length; j++)
                    //     {
                    //         if (rConfig.targetRot[i].value[j] == null)
                    //         {
                    //             rConfig.targetRot[i].value[j] = DefaultCurve;
                    //         }
                    //     }
                    // }

                    EditorUtility.SetDirty(rConfig);
                    LogGame.Log($"相机曲线{rPath}导出成功");
                }
            }
        }

        private static Transform FindChild(Transform parent, string name)
        {
            if (parent.name == name)
            {
                return parent;
            }

            foreach (Transform child in parent)
            {
                // 递归查找子节点
                Transform result = FindChild(child, name);
                if (result != null)
                {
                    return result;
                }
            }
            return null;
        }
    }
}